<?php

namespace app\services;

use app\traits\Page;
use plugin\admin\app\model\Coupon;
use plugin\admin\app\model\GoodsCategoryRelation;
use plugin\admin\app\model\User;
use plugin\admin\app\model\UserCoupon;

class UserCouponService
{
    public static function receiveRegisterSendCoupons()
    {
        $coupons = CouponService::register();

        foreach ($coupons as $coupon) {
            self::give($coupon['id'], get_user_id(), true);
        }
    }

    public static function count()
    {
        return UserCoupon::where('user_id', get_user_id())->whereNull('use_time')->count();
    }

    public static function give($couponId = 0, $userId = null, $checkIfReceive = false)
    {
        $couponInfo = Coupon::where('id', $couponId)->first();

        $query = User::where('status', 0);

        if (!is_null($userId)) {
            $userId = (array) $userId;
            $query->whereIn('id', $userId);
        }

        if ($couponInfo['total_count'] > 0) {
            $restCount = $couponInfo['total_count'] - $couponInfo['receive_count'];

            if ($restCount > 0) {
                $query->offset(0)->limit($restCount);
            } else {
                throw new \Exception('优惠券已无余量');
            }
        }

        $originalUsers = $query->get()->toArray();

        $users = [];
        if ($checkIfReceive) {
            $userIds = array_column($originalUsers, 'id');
            $userCoupons = UserCoupon::where('coupon_id', $couponId)->whereIn('user_id', $userIds)->get()->toArray();
            $userCoupons = array_combine(
                array_column($userCoupons, 'user_id'),
                array_values($userCoupons)
            );

            foreach ($originalUsers as $user) {
                if (!isset($userCoupons[$user['id']])) {
                    $users[] = $user;
                }
            }

            if (count($users) == 0) {
                throw new \Exception('已领取，请勿重复领取');
            }
        } else {
            $users = $originalUsers;
        }

        $giveCount = count($users);
        $couponInfo->receive_count += $giveCount;
        $couponInfo->save();

        $insertData = [];

        foreach ($users as $user) {
            $insertData[] = [
                'user_id' => $user['id'],
                'coupon_id' => $couponInfo['id'],
                'data' => json_encode($couponInfo, JSON_UNESCAPED_UNICODE),
                'expiry_time' => strtotime('+' . $couponInfo['expiry_days'] . ' days'),
                'created_time' => time()
            ];
        }

        if (count($insertData) > 0) {
            UserCoupon::insert($insertData);
        }
    }

    public static function check($couponId)
    {
        UserCoupon::where('id', $couponId)->update(['use_time' => date('Y-m-d H:i:s')]);
    }

    public static function back($couponId)
    {
        UserCoupon::where('id', $couponId)->update(['use_time' => null]);
    }

    public static function list($page, $length = 10, $type = 0)
    {
        $offset = ($page - 1) * $length;

        $query = UserCoupon::where('user_id', get_user_id());

        switch ($type) {
            case 1:
                $query->whereNull('use_time')->where('expiry_time', '>=', time());
                break;
            case 2:
                $query->whereNotNull('use_time');
                break;
            case 3:
                $query->where('expiry_time', '<', time());
                break;
        }

        $totalCount = (clone $query)->count();
        $list = $query->offset($offset)->limit($length)->get()->toArray();

        foreach ($list as $key=>$item) {
            $couponInfo = json_decode($item['data'], true);
            $list[$key]['coupon_info'] = $couponInfo;
        }

        return Page::wrap($totalCount, $page, $length, $list);
    }

    /**
     * 获取该预览订单可用的优惠券
     *
     * @param $cartItemIds
     * @return array
     */
    public static function getOrderCouponList($cartItemIds)
    {
        $canUse = ConfigService::get('activity_coupon');

        if (!$canUse) {
            return [];
        }

        $coupons = UserCoupon::where('user_id', get_user_id())->orderByDesc('id')->get()->toArray();

        $cartItems = ShoppingCartService::list($cartItemIds, 1);

        if (empty($cartItems['list']['valid'])) {
            return [];
        }

        $goodsIds = array_column($cartItems['list']['valid'], 'goods_id');

        $relations = GoodsCategoryRelation::whereIn('goods_id', $goodsIds)->get()->toArray();
        $categoryIds = array_column($relations, 'category_id');

        foreach ($coupons as $key=>$coupon) {
            [$canUse, $statusText, $preferentialPrice] = UserCoupon::getStatusText($coupon, $categoryIds, $cartItems['totalPrice'], $goodsIds);

            $coupon['can_use'] = $canUse;
            $coupon['status_text'] = $statusText;
            $coupon['preferential_price'] = $preferentialPrice;

            $coupons[$key] = $coupon;
        }

        return $coupons;
    }

}